#ifndef _prot_H_
#define _prot_H_

#include <stdint.h>
#include <stdbool.h>
#include "protocol.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include <stdio.h>
#include "mbedtls/md5.h"

/* 设备信息结构体 */
struct serial_device_info {
    uint32_t hw_version;
    uint32_t sw_version;
    uint32_t proto_version;
};

/* U盘信息结构体 */
#define MSC_STR_DESC_SIZE 32
struct serial_udisk_info {
    uint64_t capacity;
    uint32_t sector_count;
    uint32_t sector_size;
    uint16_t id_product;
    uint16_t id_vendor;
    char manufacturer[MSC_STR_DESC_SIZE];
    char product[MSC_STR_DESC_SIZE];
    char serial_number[MSC_STR_DESC_SIZE];
};

/* 文件信息结构体 */
struct serial_file_info {
    char name[64];      // 文件名
    uint32_t type;      // 类型：0-文件，1-目录
    uint32_t mtime;     // 修改时间
    uint32_t size;      // 文件大小
} __attribute__((packed));  // 确保没有对齐填充

/* 读文件请求结构体 */
struct serial_read_request {
    uint32_t offset;
    uint32_t size;
    char path[128];
};

/* 写文件内容结构体 */
struct serial_write_content {
    uint32_t offset;
    uint32_t size;
    char content[0];  // 柔性数组
};

/* 串口接收回调函数类型 */
typedef void (*uart_rx_callback)(uint8_t *data, uint32_t len);

/* 协议处理回调函数类型 */
typedef void (*protocol_handler)(uint8_t cmd, const uint8_t *data, uint32_t len);

/* 设置协议处理回调函数 */
void prot_set_protocol_handler(protocol_handler handler);

/* 串口相关接口 */
bool prot_uart_init(int uart_num, int baud_rate);
bool prot_uart_send(const uint8_t *data, uint32_t len);
void prot_uart_set_rx_callback(uart_rx_callback cb);

/* 反初始化接口 */
void prot_deinit(void);

/* 设备信息接口 */
void prot_get_device_info(struct serial_device_info *info);
bool prot_get_udisk_info(struct serial_udisk_info *info);

/* 文件操作接口 */
int prot_get_file_list(const char *path, struct serial_file_info **list, int max_count);
bool prot_mkdir(const char *path);
int prot_read_file(const char *path, uint32_t offset, uint8_t *buf, uint32_t size);
bool prot_write_file_start(const char *path);
bool prot_write_file_data(uint32_t offset, const uint8_t *data, uint32_t size);
bool prot_write_file_end(uint8_t *md5_out);

void prot_set_udisk_inserted(bool set);

#define PING_PONG_BUF_SIZE (1*1024*1024)  // ping-pong buffer 大小为1MB

/* 读取文件时的回调函数类型 */
typedef void (*read_data_callback)(const uint8_t *data, uint32_t size);

/* 异步读取文件接口 */
bool prot_read_file_async(const char *path, uint32_t offset, uint32_t size, read_data_callback cb);

/* 定义 ping-pong 缓冲区结构 */
typedef struct {
    uint8_t *buf;           // 缓冲区指针
    uint32_t size;          // 缓冲区大小
    uint32_t data_size;     // 实际数据大小
    uint32_t file_offset;   // 文件偏移量
    bool is_ready;          // 数据是否就绪
} buffer_block_t;

typedef struct {
    buffer_block_t ping;    // ping 缓冲区
    buffer_block_t pong;    // pong 缓冲区
    bool is_ping;           // 当前是否使用 ping
    FILE *fp;               // 文件指针
    SemaphoreHandle_t sem;  // 同步信号量
} pingpong_buffer_t;

#define MD5_HASH_LENGTH 16

#endif /* _prot_H_ */
